package com.example.rwq_test.aqs;

import java.util.HashMap;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;

/**
 * TODO note
 *
 * @author renweiqiang
 * @version 1.0.0
 * @createTime 2022/12/26
 */
public class CountDownLatchDemo {
    public static void main(String[] args) {
        HashMap<String, CountDownLatch> map = new HashMap<>();
        String key = "main";
        System.out.println("main start.");
        CountDownLatch countDownLatch = new CountDownLatch(3);
        map.put(key, countDownLatch);
        for (int i = 0; i <3; i++) {
            new Thread(() -> {
                System.out.println("main new Thread start.");
                doSomeThing();
                System.out.println("main new Thread end.");
                countDownLatch.countDown();
            }).start();
        }
        System.out.println("main ing.");
        try {
            if (map.get(key).await(5000, TimeUnit.MILLISECONDS)) {
                System.out.println("main await success.");
            } else {
                System.out.println("main await fail.");
            }
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
        System.out.println("main end.");


//        doAwait1();
//        System.out.println("<<==============================================>>");
//        doAwait21();
//        System.out.println("<<==============================================>>");
//        doAwait2();
//        System.out.println("<<==============================================>>");
//        doAwait22();
//        System.out.println("<<==============================================>>");
//        doAwait31();
//        System.out.println("<<==============================================>>");
//        doAwait3();
//        System.out.println("<<==============================================>>");
//        doAwait32();
//        System.out.println("<<==============================================>>");
//        doAwait4();
    }

    private static void doAwait4() {
        System.out.println("doAwait4 start.");
        CountDownLatch countDownLatch = new CountDownLatch(1);
        new Thread(() -> {
            System.out.println("doAwait4 new Thread start.");
            for (int i = 0; i <7; i++) {
                doSomeThing();
            }
            System.out.println("doAwait4 new Thread end.");
            countDownLatch.countDown();
        }).start();
        System.out.println("doAwait4 ing.");
        try {
            if (countDownLatch.await(5000, TimeUnit.MILLISECONDS)) {
                System.out.println("doAwait4 await success.");
            } else {
                System.out.println("doAwait4 await fail.");
            }
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
        System.out.println("doAwait4 end.");
    }

    private static void doAwait31() {
        System.out.println("doAwait31 start.");
        CountDownLatch countDownLatch = new CountDownLatch(1);
        new Thread(() -> {
            System.out.println("doAwait31 new Thread start.");
            for (int i = 0; i <5; i++) {
                doSomeThing();
            }
            System.out.println("doAwait31 new Thread end.");
            countDownLatch.countDown();
        }).start();

        System.out.println("doAwait31 ing.");
        try {
            if (countDownLatch.await(4999, TimeUnit.MILLISECONDS)) {
                System.out.println("doAwait31 await success.");
            } else {
                System.out.println("doAwait31 await fail.");
            }
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
        System.out.println("doAwait31 end.");
    }

    private static void doAwait3() {
        System.out.println("doAwait3 start.");
        CountDownLatch countDownLatch = new CountDownLatch(1);
        new Thread(() -> {
            System.out.println("doAwait3 new Thread start.");
            for (int i = 0; i <5; i++) {
                doSomeThing();
            }
            System.out.println("doAwait3 new Thread end.");
            countDownLatch.countDown();
        }).start();

        System.out.println("doAwait3 ing.");
        try {
            if (countDownLatch.await(5000, TimeUnit.MILLISECONDS)) {
                System.out.println("doAwait3 await success.");
            } else {
                System.out.println("doAwait3 await fail.");
            }
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
        System.out.println("doAwait3 end.");
    }

    private static void doAwait32() {
        System.out.println("doAwait32 start.");
        CountDownLatch countDownLatch = new CountDownLatch(1);
        new Thread(() -> {
            System.out.println("doAwait32 new Thread start.");
            for (int i = 0; i <5; i++) {
                doSomeThing();
            }
            System.out.println("doAwait32 new Thread end.");
            countDownLatch.countDown();
        }).start();

        System.out.println("doAwait32 ing.");
        try {
            if (countDownLatch.await(5001, TimeUnit.MILLISECONDS)) {
                System.out.println("doAwait32 await success.");
            } else {
                System.out.println("doAwait32 await fail.");
            }
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
        System.out.println("doAwait32 end.");
    }

    private static void doAwait21() {
        System.out.println("doAwait21 start.");
        CountDownLatch countDownLatch = new CountDownLatch(1);
        new Thread(() -> {
            System.out.println("doAwait21 new Thread start.");
            for (int i = 0; i <3; i++) {
                doSomeThing();
            }
            System.out.println("doAwait21 new Thread end.");
            countDownLatch.countDown();
        }).start();

        System.out.println("doAwait21 ing.");
        try {
            countDownLatch.await(5000, TimeUnit.MILLISECONDS);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
        System.out.println("doAwait21 end.");
    }

    private static void doAwait2() {
        System.out.println("doAwait2 start.");
        CountDownLatch countDownLatch = new CountDownLatch(1);
        new Thread(() -> {
            System.out.println("doAwait2 new Thread start.");
            for (int i = 0; i <3; i++) {
                doSomeThing();
            }
            System.out.println("doAwait2 new Thread end.");
            countDownLatch.countDown();
        }).start();

        System.out.println("doAwait2 ing.");
        try {
            if (countDownLatch.await(5000, TimeUnit.MILLISECONDS)) {
                System.out.println("doAwait2 await success.");
            } else {
                System.out.println("doAwait2 await fail.");
            }
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
        System.out.println("doAwait2 end.");
    }

    private static void doAwait22() {
        System.out.println("doAwait22 start.");
        CountDownLatch countDownLatch = new CountDownLatch(1);
        new Thread(() -> {
            System.out.println("doAwait22 new Thread start.");
            for (int i = 0; i <7; i++) {
                doSomeThing();
            }
            System.out.println("doAwait22 new Thread end.");
            countDownLatch.countDown();
        }).start();

        System.out.println("doAwait22 ing.");
        try {
            countDownLatch.await(5000, TimeUnit.MILLISECONDS);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
        System.out.println("doAwait22 end.");
    }

    private static void doAwait1() {
        System.out.println("doAwait1 start.");
        CountDownLatch countDownLatch = new CountDownLatch(1);
        new Thread(() -> {
            System.out.println("doAwait1 new Thread start.");
            for (int i = 0; i < 5; i++) {
                doSomeThing();
            }
            System.out.println("doAwait1 new Thread end.");
            countDownLatch.countDown();
        }).start();

        System.out.println("doAwait1 ing.");
        try {
            countDownLatch.await();
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
        System.out.println("doAwait1 end.");
    }

    private static void doSomeThing() {
        try {
            TimeUnit.MILLISECONDS.sleep(1000);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
    }
}
